#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#define MAXSIZ 4096
#define FIFOLEN 128

void* func_1(void* args)
{
    pthread_t tid = pthread_self();
    int fd = 0;
    char buf[MAXSIZ] = "String from func_1 to func_2";
    int num;
    char fifoname[FIFOLEN] ;
    sprintf(fifoname, "%lu", (unsigned long)tid);
    /*memset(buf,0,MAXSIZ);*/
    
    int ret = mkfifo(fifoname, 0777);
    if (ret != 0) {
        fprintf(stderr, "Counld not create fifo %s/n",fifoname);
        exit(EXIT_FAILURE);
    } else {
        printf("FIFO %s creation success!\n",fifoname);
    }

    fd = open(fifoname, O_WRONLY);

    if (fd != -1) {
        ret = write(fd, buf, MAXSIZ);
        if (ret == -1) {
            fprintf(stderr, "write error on pipe\n");
            exit(EXIT_FAILURE);
        }
    }

    printf("func_1 thread id %lu\n", (unsigned long)tid);
    close(fd);
}

void* func_2(void* args)
{
    char fifoname[FIFOLEN];
    int fd;
    char buf[MAXSIZ];
    int num, ret;
    memset(buf,0,MAXSIZ);


    sprintf(fifoname, "./%lu", (unsigned long)args);
    sleep(3);
    fd = open(fifoname, O_RDONLY);
    printf("IN FUN_2, fifoname : %s\n", fifoname);
    if (fd != -1) {
        ret = read(fd, buf, MAXSIZ);
        if (ret == -1) {
            fprintf(stderr, "write error on pipe\n");
            exit(EXIT_FAILURE);
        }
        printf("This is func_2. Receive message from %s: %s", fifoname, buf);
    }
    close(fd);
}


int main()
{
    pthread_t pid1, pid2;
    char fifoname[] = "/tmp/tmpfifo";

    /*int ret_val = mkfifo(pipeName, 0666);*/
  /*if ((ret_val == -1) && (errno != EEXIST)) {*/
    /*perror("Error creating the named pipe");*/
  /*}*/
  /*Open both ends within this process in on-blocking mode*/
  /*Must do like this otherwise open call will wait*/
  /*till other end of pipe is opened by another process*/
  /*int readFd = open(pipeName, O_RDONLY|O_NONBLOCK);*/
  /*int writeFd = open(pipeName, O_WRONLY|O_NONBLOCK);*/
    if(pthread_create(&pid1, NULL, func_1, NULL)){
        return -1;
    }

    if(pthread_create(&pid2, NULL, func_2, (void*)pid1)){
        return -1;
    }
    while(1){
        sleep(1) ;
    }

    return 0;
}
